En primer lugar, como la red eléctrica no permite extraer más de dos años consecutivos de datos, hemos dividido la descarga en tres archivos. Los datos se obtuvieron a través de la API y, mediante un programa en Python, los convertimos a formato CSV para facilitar su tratamiento en R.
Nuestro análisis incluye el año 2015 y los años entre 2020 y 2024 ambos incluidos, ya que consideramos que este periodo es suficiente para observar las diferencias y cambios ocurridos en los últimos años con la evolución de energias renovables y no renovables.
Primer paso : importar las librerias que vamos a usar y juntar las bases de datos
# Manipular los datos
library(dplyr)
# Para el manejo de las fechas
library(lubridate)
# Creación de graficos
library(ggplot2)
# Para los graficos interactivos
library(plotly)
# Formateo de graficos
library(scales)
# Para leer los archivos csv
library(readr)
# Unir las baes de datos
df_2020_2021_t = read.csv('generacion_total_2020_2021.csv')
df_2022_2023_t = read.csv('generacion_total_2022_2023.csv')
df_2024_2025_t = read.csv('generacion_total_2024_2025.csv')
df_2015_t = read.csv('generacion2015.csv')
# Unir los dataframes
df_completo_1 = bind_rows(df_2024_2025_t, df_2022_2023_t, df_2020_2021_t,df_2015_t)
Segundo paso: Añadir columnas para el tratamiento de los datos
En primer lugar, transformamos las fechas y creamos una nueva columna desglosando el día, el mes y el año. A continuación, añadimos una columna que indica si la fuente de energía es renovable o no, utilizando los valores “sí” o “no” según corresponda. Por último, incorporamos otra columna para señalar si la fuente de energía emite CO₂, también con los valores “sí” o “noSegundo paso: Añadir columnas para el tratamiento de los datos
En primer lugar, transformamos las fechas y creamos una nueva columna desglosando el día, el mes y el año. A continuación, añadimos una columna que indica si la fuente de energía es renovable o no, utilizando los valores “sí” o “no” según corresponda. Por último, incorporamos otra columna para señalar si la fuente de energía emite CO₂, también con los valores “sí” o “no”.
TODAS_ENERGIAS <- df_completo_1 %>%
mutate(
# Convertimos a objeto de fecha
Fecha = as.Date(datetime),
# Extraemos año, mes y día
Año = year(datetime),
Mes = month(datetime),
Dia = day(datetime)
)
TODAS_ENERGIAS <- TODAS_ENERGIAS %>%
select(-datetime)
# Añadir una columna para ver si son o no renovables si o no
tecnologias_renovables <- c("Hidráulica", "Eólica", "Solar fotovoltaica",
"Solar térmica", "Otras renovables",
"Residuos renovables", "Hidroeólica")
TODAS_ENERGIAS <- TODAS_ENERGIAS %>%
mutate(Renovable = ifelse(tech_type %in% tecnologias_renovables, "Sí", "No"))
# Añadir una columna para emisiones de CO2
tecnologias_emisoras_co2 <- c("Carbón", "Ciclo combinado", "Cogeneración",
"Residuos no renovables", "Motores diésel",
"Turbina de gas", "Fuel + Gas", "Turbina de vapor")
# Añadir columna Emisora_CO2
TODAS_ENERGIAS <- TODAS_ENERGIAS %>%
mutate(Emisora_CO2 = ifelse(tech_type %in% tecnologias_emisoras_co2, "Sí", "No"))
head(TODAS_ENERGIAS)
## geo_id community_name tech_type tech_id groupId value percentage
## 1 4 Andalucía Hidráulica 10330 1 11457.93 0.00480690
## 2 4 Andalucía Hidráulica 10330 1 26755.85 0.01158728
## 3 4 Andalucía Hidráulica 10330 1 39191.07 0.01753536
## 4 4 Andalucía Hidráulica 10330 1 38972.64 0.01739713
## 5 4 Andalucía Hidráulica 10330 1 50085.30 0.01860116
## 6 4 Andalucía Hidráulica 10330 1 63497.79 0.02510813
## Fecha Año Mes Dia Renovable Emisora_CO2
## 1 2024-01-01 2024 1 1 Sí No
## 2 2024-02-01 2024 2 1 Sí No
## 3 2024-03-01 2024 3 1 Sí No
## 4 2024-04-01 2024 4 1 Sí No
## 5 2024-05-01 2024 5 1 Sí No
## 6 2024-06-01 2024 6 1 Sí No
El primer análisis realizado fue un gráfico de barras que compara la producción energética del año 2015 con la de los últimos cuatro años (2020-2024), con el objetivo de observar cómo ha evolucionado. Para evitar duplicidades, se omitió la producción total.
En el eje X se representan los distintos tipos de energía, mientras que en el eje Y se muestra la cantidad de producción. Además, sobre cada barra se incluye el porcentaje que representa cada tipo de energía respecto al total anual.
resumen_renovable_2015 <- TODAS_ENERGIAS %>%
filter(!is.na(tech_type),
tech_type != "Todas",
tech_type != "Generación total",
Año == 2015) %>%
group_by(tech_type) %>%
summarise(Produccion_total = sum(value, na.rm = TRUE) / 1e6) %>% # millones
mutate(Porcentaje = Produccion_total / sum(Produccion_total) * 100) %>%
arrange(desc(Produccion_total))
ggplot(resumen_renovable_2015, aes(x = reorder(tech_type, -Produccion_total), y = Produccion_total)) +
geom_bar(stat = "identity", fill = "#009E73") +
geom_text(aes(label = paste0(round(Porcentaje, 1), "%")), vjust = -0.5, size = 3.5) +
labs(title = "Producción por Tipo de Energía Renovable en 2015",
x = "Tipo de Energía Renovable",
y = "Producción Total (millones de unidades)") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
resumen_renovable_2020_2024 <- TODAS_ENERGIAS %>%
filter(!is.na(tech_type),
tech_type != "Todas",
tech_type != "Generación total",
Año >= 2020,
Año <= 2024) %>%
group_by(tech_type) %>%
summarise(Produccion_total = sum(value, na.rm = TRUE) / 1e6) %>% # millones
mutate(Porcentaje = Produccion_total / sum(Produccion_total) * 100) %>%
arrange(desc(Produccion_total))
ggplot(resumen_renovable_2020_2024, aes(x = reorder(tech_type, -Produccion_total), y = Produccion_total)) +
geom_bar(stat = "identity", fill = "#009E73") +
geom_text(aes(label = paste0(round(Porcentaje, 1), "%")), vjust = -0.5, size = 3.5) +
labs(title = "Producción por Tipo de Energía Renovable (2020–2024)",
x = "Tipo de Energía Renovable",
y = "Producción Total (millones de unidades)") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Aquí se presenta un gráfico de barras por años que compara la producción de energía renovable y no renovable, mostrando además el porcentaje que representa cada una sobre el total de producción anual.
# Filtrar y agrupar por año y tipo de energía (renovable/no renovable)
datos_por_año <- TODAS_ENERGIAS %>%
filter(community_name != "Todas",
tech_type != "Generación total") %>% # <- Excluir Generación total
group_by(Año, Renovable) %>%
summarise(Produccion_Total = sum(value, na.rm = TRUE)) %>%
ungroup() %>%
group_by(Año) %>%
mutate(Porcentaje = Produccion_Total / sum(Produccion_Total) * 100) %>%
ungroup()
## `summarise()` has grouped output by 'Año'. You can override using the `.groups`
## argument.
# Gráfico de barras con porcentajes
ggplot(datos_por_año, aes(x = factor(Año),
y = Produccion_Total / 1e6, # Convertir a millones
fill = Renovable)) +
geom_col(position = "dodge", width = 0.7) +
geom_text(aes(label = paste0(round(Porcentaje, 1), "%")),
position = position_dodge(width = 0.7),
vjust = -0.5, size = 3.5) +
scale_fill_manual(values = c("Sí" = "#4daf4a", # Verde para renovables
"No" = "#e41a1c"), # Rojo para no renovables
labels = c("Sí" = "Renovable", "No" = "No renovable")) +
labs(title = "Generación total de energía por año en España",
subtitle = "Distribución entre energías renovables y no renovables",
x = "Año",
y = "Generación (millones de unidades)",
fill = "Tipo de energía") +
scale_y_continuous(labels = comma,
expand = expansion(mult = c(0, 0.1))) +
theme_minimal(base_size = 12) +
theme(legend.position = "top",
plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(color = "gray40"),
panel.grid.major.x = element_blank())
## 4.2.2 ANALISIS ENERGIAS NO RENOVSBLES
En este caso, se ha creado una función para identificar, dentro del grupo de energías no renovables, cuál ha sido la más utilizada en cada año. Además, se analiza cómo ha evolucionado su producción desde 2015 hasta 2024. También se clasifica cada fuente según sus emisiones de CO₂: las emisoras se representan en color rojo y las no emisoras, en verde.
Se evidencia una transformación significativa hacia un modelo energético más sostenible.
Las mas siginificativas son, a solar fotovoltaica aumentó su participación del 3,1 % en 2015 al 11,2 % en los últimos 4 años.La eólica creció del 11 % al 23 % en el mismo periodo.
Caída de las fuentes no renovables: El carbón redujo su participación del 19,9 % al 1,9 %, prácticamente desapareciendo del mix energético.
Mayor protagonismo de las renovables:
En 2023, las energías renovables superaron el 50 % de la producción total.Este hito acerca a España al objetivo del 70 % de generación renovable para 2030.
Factores impulsores del crecimiento renovable:
Reducción de los costes tecnológicos.
Mejora del marco normativo.
Aplicación de planes estratégicos como el Plan Nacional Integrado de Energía y Clima (PNIEC).
grafico_produccion_no_renovable <- function(datos, año) {
datos_grafico <- datos %>%
filter(Renovable == "No",
tech_type != "Generación total",
Año == año) %>%
group_by(tech_type, Emisora_CO2) %>%
summarise(Producción_total = sum(value, na.rm = TRUE)) %>%
ungroup() %>%
mutate(Porcentaje = Producción_total / sum(Producción_total),
Etiqueta = paste0(round(Porcentaje * 100, 1), "%"))
ggplot(datos_grafico, aes(x = tech_type, y = Porcentaje, fill = Emisora_CO2)) +
geom_bar(stat = "identity", position = position_dodge(width = 0.9)) +
geom_text(aes(label = Etiqueta),
position = position_dodge(width = 0.9),
vjust = -0.5,
size = 3) +
labs(title = paste("Porcentaje de Producción por Tecnología No Renovable en", año),
x = "Tecnología",
y = "Porcentaje de Producción",
fill = "Emite CO2") +
theme_minimal() +
scale_y_continuous(labels = percent_format(scale = 1), limits = c(0, max(datos_grafico$Porcentaje) * 1.15)) +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +
scale_fill_manual(values = c("Sí" = "#e41a1c", "No" = "#4daf4a"))
}
grafico_produccion_no_renovable(TODAS_ENERGIAS, 2015)
## `summarise()` has grouped output by 'tech_type'. You can override using the
## `.groups` argument.
grafico_produccion_no_renovable(TODAS_ENERGIAS, 2024)
## `summarise()` has grouped output by 'tech_type'. You can override using the
## `.groups` argument.
Aunque sería posible mostrar los gráficos correspondientes a todos los
años, con estos dos ejemplos es suficiente para apreciar la notable
diferencia en la producción energética a lo largo del tiempo.
La energía nuclear sigue desempeñando un papel fundamental dentro del grupo de energías gracias a su capacidad para generar electricidad de manera constante sin emitir CO₂. En 2024, representa el 46,3 % de la producción no renovable y el 20,9 % del total, siendo crucial para garantizar la estabilidad del sistema eléctrico, especialmente en periodos de baja producción renovable. En 2015, la nuclear también era la principal fuente de energía no renovable, junto con el carbón.
El ciclo combinado (basado en gas natural) sigue siendo una tecnología importante debido a su capacidad de respuesta rápida y disponibilidad continua. Aunque es emisora de gases de efecto invernadero, en 2024 representa el 31,6 % de la energía no renovable y el 18,3 % del total, actuando como respaldo en momentos de alta demanda o baja generación renovable.
En 2015, la producción de energía a partir del carbón representaba aproximadamente el 30 % de la producción no renovable y el 19 % del total de la generación eléctrica en España. Sin embargo, para 2024 esta cifra se ha reducido drásticamente, quedando en solo un 2,7 % de la producción no renovable y un 2 % del total. Esta caída refleja el progresivo abandono de esta fuente altamente contaminante, impulsado por políticas de descarbonización, el cierre de centrales térmicas y el impulso a las energías renovables.
El análisis comienza evaluando cada una de estas energías de forma individual y estacionaria, para posteriormente analizarlas de manera conjunta. En primer lugar, se analiza la energía eólica, para lo cual se crea una función general que permite estudiar cualquier tipo de energía de forma estacionaria.
meses_es <- c("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",
"Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre")
TODAS_ENERGIAS$Mes <- factor(TODAS_ENERGIAS$Mes, levels = 1:12, labels = meses_es)
# Definir tipos de energía (corregido el nombre de la variable)
tipos_energia = c("Hidráulica", "Carbón", "Ciclo combinado", "Eólica",
"Solar fotovoltaica", "Solar térmica", "Otras renovables",
"Cogeneración", "Residuos no renovables", "Generación total",
"Residuos renovables", "Nuclear", "Motores diésel",
"Turbina de gas", "Fuel + Gas", "Turbina de vapor", "Hidroeólica")
# Agrupar y resumir por Año, Mes y Tipo de energía (usando nombre de columna consistente)
resumen_mensual <- TODAS_ENERGIAS %>%
filter(tech_type %in% tipos_energia) %>% # Usar la variable correcta
group_by(Año, Mes, tech_type) %>% # Mantener consistencia en nombre de columna
summarise(Produccion = sum(value, na.rm = TRUE) / 1e6, .groups = "drop")
# Función para graficar por tipo de energía
graficar_por_tipo <- function(tipo_energia) {
# Filtrar los datos para el tipo de energía
datos_filtrados <- resumen_mensual %>% filter(tech_type == tipo_energia)
p <- ggplot(datos_filtrados, aes(x = Mes, y = Produccion, group = Año, color = factor(Año))) +
geom_line(size = 1.2) +
geom_point(size = 2) +
labs(title = paste("Producción mensual de energía", tipo_energia),
x = "Mes", y = "Producción (millones de unidades)", color = "Año") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
print(p)
return(ggplotly(p))
}
graficar_por_tipo( "Solar fotovoltaica")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Como se puede obervar en este grafico interactivo. A pesar de su falta de capacidad de regulación, su crecimiento ha sido exponencial, y actualmente juega un papel central en los meses de mayor radiación solar, Su producción se concentra en las horas centrales del día, lo que plantea retos relacionados con la gestión de excedentes y la necesidad de sistemas de almacenamiento eficientes.
graficar_por_tipo("Eólica")
Por otro lado la eólica, su generación se concentra entre los meses de octubre y abril, cuando los vientos son más frecuentes. Durante el verano y el inicio del otoño, la baja disponibilidad de viento reduce la producción de estas fuentes, lo que obliga a reforzar el suministro con otras tecnologías.
Si comparamos entre ellas:
# Filtrar solo tecnologías Eólica y Solar fotovoltaica
renovables_no_gestionables <- TODAS_ENERGIAS %>%
filter(tech_type %in% c("Eólica", "Solar fotovoltaica")) %>%
mutate(
tech_type = ifelse(tech_type == "Solar fotovoltaica", "Solar", tech_type)
)
# Agrupar por año, mes y tecnología
datos_mensuales_solar_eolica <- renovables_no_gestionables %>%
group_by(Año, Mes, tech_type) %>%
summarise(Generacion = sum(value, na.rm = TRUE)) %>%
ungroup()
## `summarise()` has grouped output by 'Año', 'Mes'. You can override using the
## `.groups` argument.
# Obtener años únicos
años_unicos_se <- unique(datos_mensuales_solar_eolica$Año)
años_unicos_se <- años_unicos_se[años_unicos_se != 2025]
# Crear gráfico por año
for (año in años_unicos_se) {
datos_año <- datos_mensuales_solar_eolica %>% filter(Año == año)
p <- ggplot(datos_año, aes(x = factor(Mes), y = Generacion, group = tech_type)) +
geom_line(aes(color = tech_type), size = 1) +
geom_point(aes(color = tech_type), size = 2) +
labs(
title = paste("Variabilidad mensual de generación - Solar fotovoltaica y Eólica - Año", año),
x = "Mes",
y = "Generación (MWh)",
color = "Tecnología"
) +
scale_x_discrete(labels = month.abb) +
theme_minimal() +
theme(legend.position = "bottom")
print(p)
}
Observamos que, en los últimos años, la producción eólica y solar
tienden a compensarse mutuamente: cuando la producción eólica disminuye,
la solar suele aumentar, y viceversa. Esta dinámica ayuda a equilibrar
la generación renovable total, mejorando la estabilidad del suministro
eléctrico. En cambio, en 2015 esta compensación no era tan marcada, ya
que las subidas en la producción solar no lograban contrarrestar
suficientemente las bajadas de la eólica, lo que provocaba mayores
fluctuaciones en la generación renovable. En los gráficos anteriores,
presentamos un análisis histórico de todos los años estudiados que
muestra cómo esta relación complementaria se ha ido fortaleciendo con el
tiempo.
Una de ellas si que es regulable i la otra no po lo que primero haremos el analisi estacionario de la hidraulica el de la eolica esta arriba en el anexo 3
graficar_por_tipo( "Hidráulica")
La energía hidráulica destaca por su capacidad de ser almacenada y liberada en función de la demanda, actuando como una “batería natural”. Su producción aumenta en invierno y primavera, coincidiendo con la mayor disponibilidad de agua por las lluvias.
Si las comparamos de forma estacionaria y por años:
# Filtrar solo las tecnologías eólica e hidráulica
eolica_hidraulica <- TODAS_ENERGIAS %>%
filter(tech_type %in% c("Eólica", "Hidráulica"))
# Resumir datos por mes y año
datos_mensuales_eh <- eolica_hidraulica %>%
group_by(Año, Mes, tech_type) %>%
summarise(Generacion = sum(value, na.rm = TRUE)) %>%
ungroup()
## `summarise()` has grouped output by 'Año', 'Mes'. You can override using the
## `.groups` argument.
# Obtener los años únicos desde el dataframe correcto
años_unicos_eh <- unique(datos_mensuales_eh$Año)
años_unicos_eh = años_unicos_eh[años_unicos_eh != 2025]
# Crear gráfico para cada año
for (año in años_unicos_eh) {
datos_año <- datos_mensuales_eh %>% filter(Año == año)
p <- ggplot(datos_año, aes(x = factor(Mes), y = Generacion, group = tech_type)) +
geom_line(aes(color = tech_type), size = 1) +
geom_point(aes(color = tech_type), size = 2) +
labs(
title = paste("Variabilidad mensual de generación - Eólica e Hidráulica - Año", año),
x = "Mes",
y = "Generación (MWh)",
color = "Tecnología"
) +
scale_x_discrete(labels = month.abb) +
theme_minimal() +
theme(legend.position = "bottom")
print(p)
}
## CONCLUSIONES 4.5 Como podemos observar, la energía eólica y la
hidráulica siguen patrones estacionales bastante similares: cuando la
producción eólica disminuye, la hidráulica también tiende a bajar, y
viceversa. Esto se debe a que ambas tecnologías están influenciadas por
condiciones meteorológicas y estacionales parecidas. No obstante, a lo
largo de todos los años analizados, la producción eólica ha sido
consistentemente superior a la hidráulica, manteniéndose como una de las
principales fuentes renovables del mix energético español.
Para la realización del clustering, se han importado los siguientes paquetes de R:
tidyverse: Conjunto de herramientas para ciencia de datos, incluye dplyr, ggplot2, tidyr, readr, entre otros, que facilitan la manipulación, visualización e importación de datos.
lubridate: Manejo sencillo de fechas y horas.
cluster: Métodos de agrupamiento como PAM y clustering jerárquico.
factoextra: Visualización de resultados de clustering y análisis multivariantes con ggplot2.
mapSpain y sf: Para trabajar con datos espaciales y generar mapas temáticos de España.
grid y gridExtra: Organización y combinación de gráficos.
RColorBrewer y scales: Paletas de colores y personalización de escalas en gráficos.
ggrepel: Mejora la colocación de etiquetas en gráficos evitando solapamientos.
library(tidyverse)
library(lubridate)
library(cluster)
library(factoextra)
library(mapSpain)
library(sf)
library(grid)
library(gridExtra)
library(RColorBrewer)
library(scales)
library(ggrepel)
library(ggsci)
TODAS_ENERGIAS<- TODAS_ENERGIAS[TODAS_ENERGIAS$community_name != "Todas", ]
En este caso solo haremos clustering del 2024 para ver como se agrupan las comunidades autonomas segun el tipo de produccion es decir el perfil energetico segun producción. Ademas quitamos las filas que representan a todas las comunidades autonomas juntas y la generacón toal para no duplicar.
df <- TODAS_ENERGIAS %>%
filter(
Año == 2024,
community_name != "Todas",
tech_type != "Generación total"
) %>%
group_by(community_name, Mes) %>%
summarise(valor_total = sum(value, na.rm = TRUE), .groups = "drop")
df_wide <- df %>%
pivot_wider(names_from = Mes, values_from = valor_total)
mat <- df_wide %>%
column_to_rownames("community_name") %>%
as.matrix()
En este paso reorganizamos los datos utilizando un pivot, de modo que las comunidades autónomas queden como filas y los meses del año como columnas, simulando una estructura de serie temporal que facilita su análisis. Posteriormente, convertimos el resultado en una matriz numérica para poder aplicar cálculos y métodos de clustering.
mat_s <- scale(mat)
Escalamos la matriz para que aunque todos las variables estan en las mismas unidades no haya variables distintas con rangos muy diferentes y que despues interfieran el el algoritmo.
Optamos por una medida de distancia basada en la similitud porque nuestro objetivo es identificar comunidades autónomas con patrones de producción energética similares, independientemente de los valores absolutos de producción.
Para ello, utilizamos la correlación de Spearman como métrica de similitud, ya que esta evalúa la relación entre los rangos de dos variables. Esto permite detectar relaciones monótonas (crecientes o decrecientes), aunque no sean lineales.
Además, al basarse en rangos y no en valores absolutos, Spearman reduce el impacto de los valores extremos: un valor atípico solo afecta la posición relativa (rango), sin distorsionar de forma excesiva la medida de similitud, como sí ocurre con métricas sensibles a la magnitud como la media o la varianza. ## 4.6.3 MAPA DE CALOR
sim_mat <- cor(t(mat_s), method = "spearman")
diss_mat <- as.dist(1 - sim_mat)
fviz_dist(diss_mat, show_labels = TRUE, lab_size = 6,
gradient = list(low = "#00AFBB", mid = "white", high = "#FC4E07")) +
ggtitle("Dissimilarity (1 - Spearman) entre comunidades")
Al interpretar el gráfico de distancias (heatmap), podemos identificar qué comunidades autónomas comparten patrones de producción energética similares.
La diagonal principal, donde la distancia es 0, representa la comparación de cada comunidad consigo misma.
Las zonas en azul indican pares de comunidades con mayor similitud en sus perfiles energéticos a lo largo del año.
Las áreas en naranja o rojo reflejan comunidades cuyos patrones de producción difieren considerablemente.
En resumen, este heatmap proporciona una visión rápida e intuitiva de la similitud o diferencia entre comunidades según su comportamiento energético mensual en 2024.
Para decidir el metodo de agrupamiento y el numero de clusters compararemos una serie de modelos como el metodo de Ward, K-medias y K-medioides:
p1 <- fviz_nbclust(mat_s, FUNcluster = hcut, method = "silhouette",
hc_method = "ward.D2", k.max = 10, diss = diss_mat) +
labs(title = "Silhouette - Ward")
p2 <- fviz_nbclust(mat_s, FUNcluster = hcut, method = "wss",
hc_method = "ward.D2", k.max = 10, diss = diss_mat) +
labs(title = "WSS - Ward")
grid.arrange(p1, p2, nrow = 1)
clust1 <- hclust(diss_mat, method = "ward.D2")
grupos1 <- cutree(clust1, k = 6)
table(grupos1)
## grupos1
## 1 2 3 4 5 6
## 2 1 3 4 5 4
cluster_colors <- brewer.pal(6, "Set2")
names(cluster_colors) <- as.character(1:6)
fviz_dend(clust1, k = 6, color_labels_by_k = TRUE, rect = TRUE, repel = TRUE,
palette = cluster_colors)
## Warning: The `<scale>` argument of `guides()` cannot be `FALSE`. Use "none" instead as
## of ggplot2 3.3.4.
## ℹ The deprecated feature was likely used in the factoextra package.
## Please report the issue at <https://github.com/kassambara/factoextra/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
p1 <- fviz_nbclust(mat_s, FUNcluster = kmeans, method = "silhouette",
k.max = 10, verbose = FALSE) + labs(title = "K-MEANS")
p2 <- fviz_nbclust(mat_s, FUNcluster = kmeans, method = "wss",
k.max = 10, verbose = FALSE) + labs(title = "K-MEANS")
grid.arrange(p1, p2, nrow = 1)
set.seed(100)
clust3 <- kmeans(mat_s, centers = 5, nstart = 30)
table(clust3$cluster)
##
## 1 2 3 4 5
## 6 4 2 5 2
p1 <- fviz_nbclust(mat_s, FUNcluster = pam, method = "silhouette",
k.max = 10, verbose = FALSE) + labs(title = "PAM - Silhouette")
p2 <- fviz_nbclust(mat_s, FUNcluster = pam, method = "wss",
k.max = 10, verbose = FALSE) + labs(title = "PAM - WSS")
grid.arrange(p1, p2, nrow = 1)
clust4 <- pam(diss_mat, k = 6)
table(clust4$clustering)
##
## 1 2 3 4 5 6
## 4 1 5 3 3 3
colores <- pal_npg("nrc")(6)
par(mfrow = c(1,3)) # Layout para 3 gráficos en fila
plot(silhouette(grupos1, diss_mat), col=colores, border=NA, main = "WARD")
plot(silhouette(clust3$cluster, diss_mat), col=colores, border=NA, main = "K-MEANS")
plot(silhouette(clust4$clustering, diss_mat), col=colores, border=NA, main = "PAM")
par(mfrow = c(1,3))
Tras aplicar y comparar tres técnicas de agrupamiento (Ward, K-means y k-medoides(PAM)), seleccionamos PAM como el método más adecuado para analizar los perfiles de producción energética por comunidad autónoma. El criterio principal fue el coeficiente de silhouette, que mide la coherencia interna de los clusters y su separación entre sí. El método PAM obtuvo el valor más alto, 0.36. Aunque no es un valor extremadamente alto, sí indica una estructura razonablemente clara, y por tanto, justifica su elección.
El análisis con PAM identificó seis grupos de comunidades autónomas que comparten patrones similares en la producción energética.
library(rnaturalearth)
## Warning: package 'rnaturalearth' was built under R version 4.4.3
mapa <- esp_get_ccaa()
# 1. Crear el dataframe con los clusters del modelo PAM
df_clusters <- data.frame(
community_name = names(clust4$clustering),
cluster = as.factor(clust4$clustering)
)
# 2. Tabla de equivalencias entre nombres de tu dataset y del shapefile
equivalencias <- tibble::tibble(
community_name = c(
"Andalucía", "Aragón", "Cantabria", "Castilla y León", "Castilla- La Mancha",
"Cataluña", "Comunidad Ceuta", "Comunidad Melilla", "Comunidad Valenciana", "Comunidad de Madrid",
"Comunidad de Navarra", "Extremadura", "Galicia", "Islas Baleares", "Islas Canarias",
"La Rioja", "País Vasco", "Principado de Asturias", "Región de Murcia"
),
ine.ccaa.name = c(
"Andalucía", "Aragón", "Cantabria", "Castilla y León", "Castilla - La Mancha",
"Cataluña", "Ceuta", "Melilla", "Comunitat Valenciana", "Madrid, Comunidad de",
"Navarra, Comunidad Foral de", "Extremadura", "Galicia", "Balears, Illes", "Canarias",
"Rioja, La", "País Vasco", "Asturias, Principado de", "Murcia, Región de"
)
)
# 3. Unir df_clusters con equivalencias
df_clusters_corregido <- df_clusters %>%
left_join(equivalencias, by = "community_name")
# 4. Unir con el mapa
mapa_clust <- mapa %>%
left_join(df_clusters_corregido, by = "ine.ccaa.name")
# 5. Verifica si hay NA (debería ser 0)
sum(is.na(mapa_clust$cluster)) # Debería dar 0
## [1] 0
# 6. Añadir el centroide para ubicar nombres
mapa_clust_centroides <- mapa_clust %>%
mutate(centroid = sf::st_centroid(geometry)) %>%
mutate(
lon = sf::st_coordinates(centroid)[,1],
lat = sf::st_coordinates(centroid)[,2]
)
# 7. Graficar el mapa con nombres
ggplot(mapa_clust) +
geom_sf(aes(fill = cluster), color = "white") +
geom_text(
data = mapa_clust_centroides,
aes(x = lon, y = lat, label = community_name),
size = 3,
color = "black"
) +
scale_fill_brewer(palette = "Set2", na.value = "grey80") +
labs(
title = "Clustering de comunidades autónomas según perfil energético (PAM)",
fill = "Cluster"
) +
theme_minimal()
unique(df_clusters_corregido$ine.ccaa.name)
## [1] "Andalucía" "Aragón"
## [3] "Cantabria" "Castilla y León"
## [5] "Castilla - La Mancha" "Cataluña"
## [7] "Ceuta" "Melilla"
## [9] "Comunitat Valenciana" "Madrid, Comunidad de"
## [11] "Navarra, Comunidad Foral de" "Extremadura"
## [13] "Galicia" "Balears, Illes"
## [15] "Canarias" "Rioja, La"
## [17] "País Vasco" "Asturias, Principado de"
## [19] "Murcia, Región de"
CLUSTER 1 (Extremadura, Andalucía, Murcia, Castilla-La Mancha)
CLUSTER 2 (Aragón)
CLUSTER 3 (Madrid, Cantabria, Islas Baleares, Ceuta, Melilla)
CLUSTER 4 (Galicia, Asturias, Castilla y León)
CLUSTER 5 (Cataluña, La Rioja, Islas Canarias)
CLUSTER 6 (País Vasco, Comunidad Valenciana, Navarra)